use crate::utils::color::colorize_file_name_with_icon;
use colored::Colorize;
use once_cell::sync::Lazy;
use std::collections::HashMap;
use std::path::Path;

static FILE_ICONS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
    HashMap::from([
        ("folder", "\u{f07b}"),
        ("folder-open", "\u{f07c}"),
        ("folder-home", "\u{f015}"),
        ("folder-user", "\u{f74b}"),
        ("folder-src", "\u{f121}"),
        ("folder-dist", "\u{f0e7}"),
        ("folder-node", "\u{e718}"),
        ("folder-git", "\u{e725}"),
        ("folder-app", "\u{f452}"),
        ("folder-temp", "\u{f56e}"),
        ("folder-public", "\u{f0c0}"),
        ("folder-private", "\u{f023}"),
        ("folder-desktop", "\u{f108}"),
        ("folder-download", "\u{f019}"),
        ("folder-upload", "\u{f093}"),
        ("folder-cloud", "\u{f0c2}"),
        ("folder-images", "\u{f1c5}"),
        ("folder-videos", "\u{f03d}"),
        ("folder-music", "\u{f001}"),
        ("folder-docs", "\u{f02d}"),
        ("rs", "\u{e7a8}"),
        ("rs-lib", "\u{e7a8}"),
        ("rs-mod", "\u{e7a8}"),
        ("js", "\u{e781}"),
        ("jsx", "\u{e7ba}"),
        ("ts", "\u{e628}"),
        ("tsx", "\u{e7ba}"),
        ("py", "\u{e606}"),
        ("pyc", "\u{e606}"),
        ("pyd", "\u{e606}"),
        ("pyw", "\u{e606}"),
        ("ipynb", "\u{e606}"),
        ("cpp", "\u{e61d}"),
        ("hpp", "\u{e61d}"),
        ("c", "\u{e61e}"),
        ("h", "\u{e61e}"),
        ("go", "\u{e626}"),
        ("rb", "\u{e791}"),
        ("erb", "\u{e791}"),
        ("rake", "\u{e791}"),
        ("php", "\u{e73d}"),
        ("php-old", "\u{e73c}"),
        ("java", "\u{e738}"),
        ("class", "\u{e738}"),
        ("jar", "\u{e738}"),
        ("gradle", "\u{e70e}"),
        ("scala", "\u{e737}"),
        ("cs", "\u{e77f}"),
        ("fs", "\u{e77f}"),
        ("vb", "\u{e77f}"),
        ("swift", "\u{e755}"),
        ("kt", "\u{e634}"),
        ("dart", "\u{e798}"),
        ("r", "\u{e905}"),
        ("lua", "\u{e620}"),
        ("pl", "\u{e769}"),
        ("pm", "\u{e769}"),
        ("t", "\u{e769}"),
        ("ex", "\u{e62d}"),
        ("exs", "\u{e62d}"),
        ("elm", "\u{e62c}"),
        ("clj", "\u{e768}"),
        ("cljs", "\u{e768}"),
        ("coffee", "\u{e751}"),
        ("litcoffee", "\u{e751}"),
        ("hs", "\u{e777}"),
        ("lhs", "\u{e777}"),
        ("html", "\u{f13b}"),
        ("htm", "\u{f13b}"),
        ("xhtml", "\u{f13b}"),
        ("css", "\u{f13c}"),
        ("scss", "\u{e749}"),
        ("sass", "\u{e74b}"),
        ("less", "\u{e758}"),
        ("styl", "\u{e759}"),
        ("svg", "\u{f1c5}"),
        ("woff", "\u{f031}"),
        ("woff2", "\u{f031}"),
        ("ttf", "\u{f031}"),
        ("eot", "\u{f031}"),
        ("otf", "\u{f031}"),
        ("vue", "\u{fd42}"),
        ("svelte", "\u{e655}"),
        ("astro", "\u{e7ba}"),
        ("solid", "\u{e7ba}"),
        ("angular", "\u{e75b}"),
        ("ng", "\u{e75b}"),
        ("next", "\u{e7ba}"),
        ("nuxt", "\u{fd42}"),
        ("remix", "\u{e7ba}"),
        ("preact", "\u{e7ba}"),
        ("json", "\u{e60b}"),
        ("jsonc", "\u{e60b}"),
        ("json5", "\u{e60b}"),
        ("yaml", "\u{e60b}"),
        ("yml", "\u{e60b}"),
        ("toml", "\u{e60b}"),
        ("xml", "\u{f121}"),
        ("ini", "\u{f121}"),
        ("conf", "\u{f121}"),
        ("config", "\u{f121}"),
        ("env", "\u{f462}"),
        ("env-local", "\u{f462}"),
        ("env-dev", "\u{f462}"),
        ("env-prod", "\u{f462}"),
        ("properties", "\u{f462}"),
        ("opts", "\u{f462}"),
        ("cfg", "\u{f462}"),
        ("inf", "\u{f462}"),
        ("cargo.toml", "\u{e7a8}"),
        ("cargo.lock", "\u{e7a8}"),
        ("package.json", "\u{e718}"),
        ("package-lock.json", "\u{e718}"),
        ("yarn.lock", "\u{e718}"),
        ("pnpm-lock.yaml", "\u{e718}"),
        ("requirements.txt", "\u{e606}"),
        ("pipfile", "\u{e606}"),
        ("pipfile.lock", "\u{e606}"),
        ("poetry.lock", "\u{e606}"),
        ("gemfile", "\u{e791}"),
        ("gemfile.lock", "\u{e791}"),
        ("pom.xml", "\u{e738}"),
        ("build.gradle", "\u{e70e}"),
        ("build.gradle.kts", "\u{e70e}"),
        ("cmake", "\u{e61d}"),
        ("cmakelists.txt", "\u{e61d}"),
        ("makefile", "\u{f121}"),
        ("dockerfile", "\u{e7b0}"),
        ("docker-compose.yml", "\u{e7b0}"),
        ("nginx.conf", "\u{f146}"),
        ("test.js", "\u{f45e}"),
        ("spec.js", "\u{f45e}"),
        ("test.ts", "\u{f45e}"),
        ("spec.ts", "\u{f45e}"),
        ("test.py", "\u{f45e}"),
        ("test.go", "\u{f45e}"),
        ("jest.config.js", "\u{f45e}"),
        ("cypress.json", "\u{f45e}"),
        ("playwright.config.ts", "\u{f45e}"),
        ("git", "\u{e702}"),
        ("gitignore", "\u{e702}"),
        ("gitattributes", "\u{e702}"),
        ("gitmodules", "\u{e702}"),
        ("gitkeep", "\u{e702}"),
        ("gitconfig", "\u{e702}"),
        ("hg", "\u{f223}"),
        ("hgignore", "\u{f223}"),
        ("hgrc", "\u{f223}"),
        ("svn", "\u{f1d3}"),
        ("md", "\u{f48a}"),
        ("markdown", "\u{f48a}"),
        ("mdx", "\u{f48a}"),
        ("txt", "\u{f0f6}"),
        ("rtf", "\u{f0f6}"),
        ("pdf", "\u{f1c1}"),
        ("doc", "\u{f1c2}"),
        ("docx", "\u{f1c2}"),
        ("xls", "\u{f1c3}"),
        ("xlsx", "\u{f1c3}"),
        ("ppt", "\u{f1c4}"),
        ("pptx", "\u{f1c4}"),
        ("odt", "\u{f1c2}"),
        ("ods", "\u{f1c3}"),
        ("odp", "\u{f1c4}"),
        ("pages", "\u{f1c2}"),
        ("numbers", "\u{f1c3}"),
        ("keynote", "\u{f1c4}"),
        ("tex", "\u{f034}"),
        ("latex", "\u{f034}"),
        ("texi", "\u{f034}"),
        ("texinfo", "\u{f034}"),
        ("log", "\u{f18d}"),
        ("err", "\u{f18d}"),
        ("out", "\u{f18d}"),
        ("png", "\u{f1c5}"),
        ("jpg", "\u{f1c5}"),
        ("jpeg", "\u{f1c5}"),
        ("gif", "\u{f1c5}"),
        ("bmp", "\u{f1c5}"),
        ("tiff", "\u{f1c5}"),
        ("ico", "\u{f1c5}"),
        ("webp", "\u{f1c5}"),
        ("avif", "\u{f1c5}"),
        ("psd", "\u{f1c5}"),
        ("ai", "\u{f1c5}"),
        ("eps", "\u{f1c5}"),
        ("raw", "\u{f1c5}"),
        ("cr2", "\u{f1c5}"),
        ("nef", "\u{f1c5}"),
        ("heic", "\u{f1c5}"),
        ("heif", "\u{f1c5}"),
        ("mp3", "\u{f1c7}"),
        ("wav", "\u{f1c7}"),
        ("ogg", "\u{f1c7}"),
        ("flac", "\u{f1c7}"),
        ("m4a", "\u{f1c7}"),
        ("aac", "\u{f1c7}"),
        ("wma", "\u{f1c7}"),
        ("aiff", "\u{f1c7}"),
        ("mp4", "\u{f1c8}"),
        ("avi", "\u{f1c8}"),
        ("mkv", "\u{f1c8}"),
        ("mov", "\u{f1c8}"),
        ("wmv", "\u{f1c8}"),
        ("flv", "\u{f1c8}"),
        ("webm", "\u{f1c8}"),
        ("m4v", "\u{f1c8}"),
        ("3gp", "\u{f1c8}"),
        ("ogv", "\u{f1c8}"),
        ("zip", "\u{f1c6}"),
        ("rar", "\u{f1c6}"),
        ("7z", "\u{f1c6}"),
        ("tar", "\u{f1c6}"),
        ("gz", "\u{f1c6}"),
        ("bz2", "\u{f1c6}"),
        ("xz", "\u{f1c6}"),
        ("iso", "\u{f1c6}"),
        ("dmg", "\u{f1c6}"),
        ("tgz", "\u{f1c6}"),
        ("lz", "\u{f1c6}"),
        ("tlz", "\u{f1c6}"),
        ("cpio", "\u{f1c6}"),
        ("cab", "\u{f1c6}"),
        ("sql", "\u{f1c0}"),
        ("db", "\u{f1c0}"),
        ("sqlite", "\u{f1c0}"),
        ("sqlite3", "\u{f1c0}"),
        ("mdb", "\u{f1c0}"),
        ("accdb", "\u{f1c0}"),
        ("rdb", "\u{f1c0}"),
        ("pgsql", "\u{f1c0}"),
        ("mongodb", "\u{f1c0}"),
        ("exe", "\u{f085}"),
        ("dll", "\u{f085}"),
        ("so", "\u{f085}"),
        ("dylib", "\u{f085}"),
        ("app", "\u{f085}"),
        ("out", "\u{f085}"),
        ("msi", "\u{f085}"),
        ("run", "\u{f085}"),
        ("bin", "\u{f085}"),
        ("key", "\u{f084}"),
        ("pub", "\u{f084}"),
        ("pem", "\u{f084}"),
        ("crt", "\u{f084}"),
        ("cer", "\u{f084}"),
        ("ca", "\u{f084}"),
        ("p12", "\u{f084}"),
        ("pfx", "\u{f084}"),
        ("asc", "\u{f084}"),
        ("gpg", "\u{f084}"),
        ("ssh", "\u{f084}"),
        ("keystore", "\u{f084}"),
        ("jks", "\u{f084}"),
        ("kdbx", "\u{f084}"),
        ("tf", "\u{e7b2}"),
        ("tfstate", "\u{e7b2}"),
        ("tfvars", "\u{e7b2}"),
        ("hcl", "\u{e7b2}"),
        ("yaml-tmpl", "\u{e7b2}"),
        ("helmfile", "\u{e7b2}"),
        ("dockerignore", "\u{e7b0}"),
        ("kubernetes", "\u{e7b2}"),
        ("k8s", "\u{e7b2}"),
        ("ipa", "\u{e755}"),
        ("xcodeproj", "\u{e755}"),
        ("pbxproj", "\u{e755}"),
        ("storyboard", "\u{e755}"),
        ("xib", "\u{e755}"),
        ("swift-module", "\u{e755}"),
        ("unity", "\u{e721}"),
        ("prefab", "\u{e721}"),
        ("unitypackage", "\u{e721}"),
        ("fbx", "\u{f1c5}"),
        ("blend", "\u{f1c5}"),
        ("obj", "\u{f1c5}"),
        ("gltf", "\u{f1c5}"),
        ("glb", "\u{f1c5}"),
        ("sh", "\u{f120}"),
        ("bash", "\u{f120}"),
        ("zsh", "\u{f120}"),
        ("fish", "\u{f120}"),
        ("ps1", "\u{f120}"),
        ("psm1", "\u{f120}"),
        ("psd1", "\u{f120}"),
        ("bat", "\u{f120}"),
        ("cmd", "\u{f120}"),
        ("vscode", "\u{e70c}"),
        ("vscodeignore", "\u{e70c}"),
        ("code-workspace", "\u{e70c}"),
        ("sublime-project", "\u{e7aa}"),
        ("sublime-workspace", "\u{e7aa}"),
        ("idea", "\u{e7b5}"),
        ("iml", "\u{e7b5}"),
        ("ttf", "\u{f031}"),
        ("otf", "\u{f031}"),
        ("woff", "\u{f031}"),
        ("woff2", "\u{f031}"),
        ("eot", "\u{f031}"),
        ("fnt", "\u{f031}"),
        ("fon", "\u{f031}"),
        ("ipynb", "\u{f040}"),
        ("csv", "\u{f1c3}"),
        ("tsv", "\u{f1c3}"),
        ("dat", "\u{f1c0}"),
        ("arff", "\u{f1c0}"),
        ("parquet", "\u{f1c0}"),
        ("arrow", "\u{f1c0}"),
        ("stl", "\u{f1b3}"),
        ("gcode", "\u{f1b3}"),
        ("3mf", "\u{f1b3}"),
        ("bak", "\u{f0c7}"),
        ("tmp", "\u{f1c9}"),
        ("temp", "\u{f1c9}"),
        ("swp", "\u{f1c9}"),
        ("swo", "\u{f1c9}"),
        ("swn", "\u{f1c9}"),
        ("bkp", "\u{f0c7}"),
        ("backup", "\u{f0c7}"),
        ("patch", "\u{f440}"),
        ("diff", "\u{f440}"),
        ("eslintrc", "\u{e60b}"),
        ("prettierrc", "\u{e60b}"),
        ("stylelintrc", "\u{e60b}"),
        ("babelrc", "\u{e60b}"),
        ("editorconfig", "\u{e60b}"),
        ("browserslistrc", "\u{e60b}"),
        ("todo", "\u{f14a}"),
        ("todo.md", "\u{f14a}"),
        ("todo.txt", "\u{f14a}"),
        ("changelog", "\u{f07c}"),
        ("changelog.md", "\u{f07c}"),
        ("license", "\u{f048}"),
        ("licence", "\u{f048}"),
        ("copying", "\u{f048}"),
        ("contributing", "\u{f09b}"),
        ("authors", "\u{f0c0}"),
        ("donors", "\u{f004}"),
        ("owners", "\u{f0c0}"),
        ("credits", "\u{f0c0}"),
        ("ini", "\u{f013}"),
        ("sys", "\u{f013}"),
        ("cfg", "\u{f013}"),
        ("conf", "\u{f013}"),
        ("reg", "\u{f013}"),
        ("policy", "\u{f013}"),
        ("lnk", "\u{f0c1}"),
        ("url", "\u{f0c1}"),
        ("webloc", "\u{f0c1}"),
        ("alias", "\u{f0c1}"),
        ("vbox", "\u{f108}"),
        ("vmdk", "\u{f108}"),
        ("vdi", "\u{f108}"),
        ("ova", "\u{f108}"),
        ("ovf", "\u{f108}"),
        ("nix", "\u{f313}"),
        ("nix-shell", "\u{f313}"),
        ("shell.nix", "\u{f313}"),
        ("default.nix", "\u{f313}"),
        ("flake.nix", "\u{f313}"),
        ("flake.lock", "\u{f313}"),
        ("configuration.nix", "\u{f313}"),
        ("hardware-configuration.nix", "\u{f313}"),
        ("home.nix", "\u{f313}"),
        ("nixpkgs.nix", "\u{f313}"),
        ("overlay.nix", "\u{f313}"),
        ("", "\u{f016}"),
    ])
});

pub fn get_icon(path: &Path) -> &'static str {
    if path.is_dir() {
        return get_folder_icon(path);
    }
    let filename = path
        .file_name()
        .and_then(|n| n.to_str())
        .unwrap_or("")
        .to_lowercase();

    let extension = path
        .extension()
        .and_then(|e| e.to_str())
        .unwrap_or("")
        .to_lowercase();

    if let Some(icon) = get_special_file_icon(&filename) {
        return icon;
    }
    if let Some(icon) = FILE_ICONS.get(extension.as_str()) {
        return icon;
    }
    "\u{f016}"
}

fn get_folder_icon(path: &Path) -> &'static str {
    let folder_name = path
        .file_name()
        .and_then(|n| n.to_str())
        .unwrap_or("")
        .to_lowercase();

    match folder_name.as_str() {
        "src" | "source" => FILE_ICONS.get("folder-src"),
        "dist" | "build" | "target" => FILE_ICONS.get("folder-dist"),
        "node_modules" => FILE_ICONS.get("folder-node"),
        ".git" => FILE_ICONS.get("folder-git"),
        "public" | "www" => FILE_ICONS.get("folder-public"),
        "private" => FILE_ICONS.get("folder-private"),
        "images" | "img" => FILE_ICONS.get("folder-images"),
        "docs" | "documentation" => FILE_ICONS.get("folder-docs"),
        "tests" | "test" | "specs" => FILE_ICONS.get("folder-test"),
        _ => FILE_ICONS.get("folder"),
    }
    .unwrap_or(FILE_ICONS.get("folder").unwrap_or(&"\u{f07b}"))
}

fn get_special_file_icon(filename: &str) -> Option<&'static str> {
    match filename {
        "cargo.toml" => Some(FILE_ICONS.get("rs").unwrap_or(&"\u{e7a8}")),
        "package.json" => Some(FILE_ICONS.get("js").unwrap_or(&"\u{e781}")),
        "dockerfile" | "docker-compose.yml" => {
            Some(FILE_ICONS.get("docker").unwrap_or(&"\u{e7b0}"))
        }
        "shell.nix"
        | "default.nix"
        | "flake.nix"
        | "configuration.nix"
        | "hardware-configuration.nix"
        | "home.nix"
        | "nixpkgs.nix"
        | "overlay.nix" => Some(FILE_ICONS.get("nix").unwrap_or(&"\u{f313}")),
        ".gitignore" | ".gitattributes" | ".gitmodules" => {
            Some(FILE_ICONS.get("git").unwrap_or(&"\u{e702}"))
        }
        "makefile" | "cmake" => Some(FILE_ICONS.get("build").unwrap_or(&"\u{f085}")),
        ".env" | ".env.local" | ".env.development" => {
            Some(FILE_ICONS.get("env").unwrap_or(&"\u{f462}"))
        }
        "readme.md" | "readme.txt" | "readme" => Some(FILE_ICONS.get("md").unwrap_or(&"\u{f48a}")),
        f if f.starts_with("test.") => Some(FILE_ICONS.get("test").unwrap_or(&"\u{f45e}")),
        f if f.ends_with(".test.js") || f.ends_with(".test.ts") => {
            Some(FILE_ICONS.get("test").unwrap_or(&"\u{f45e}"))
        }
        f if f.ends_with(".spec.js") || f.ends_with(".spec.ts") => {
            Some(FILE_ICONS.get("test").unwrap_or(&"\u{f45e}"))
        }
        f if f.ends_with("rc") || f.ends_with(".config.js") || f.ends_with(".config.ts") => {
            Some(FILE_ICONS.get("config").unwrap_or(&"\u{f013}"))
        }
        _ => None,
    }
}

pub fn format_with_icon(path: &Path, name: String, show_icons: bool) -> String {
    if show_icons {
        let icon_str = get_icon(path).bold();
        let with_icon = format!("{} {}", icon_str, name);
        colorize_file_name_with_icon(path, with_icon).to_string()
    } else {
        name
    }
}
